using System.Collections.Generic;
using Light;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

// UI�㼶
public enum E_UI_Layer
{
    Bot,
    Mid,
    Top,
    System
}

/// <summary>
///     �ṩ�� UI Panel �Ŀ��ٷ��ʷ���
/// </summary>
public static class PanelNameToPath
{
    /// <summary>
    ///     StatusBarPanel
    /// </summary>
    public static readonly string STATUSBARPANEL = "Prefab/UI/Panel/StatusBarPanel";
}


/// <summary>
///     UI������,��Ҫ�����ⲿ���е��õ�����
/// </summary>
public class UIManager : SingletonMono<UIManager>
{
    //��Ҫֱ�Ӳ����Ļ���
    public RectTransform canvas;

    private Transform bot;
    private Transform mid;
    public Dictionary<string, BasePanel> panelDic = new();

    public Dictionary<string, BasePanel> registerPanel = new(); //��������ע���Panel
    private Transform system;
    private Transform top;

    private UIManager()
    {
    }

    protected override void Awake()
    {
        base.Awake();

        //�ҵ�����
        bot = canvas.transform.Find("bot");
        mid = canvas.transform.Find("mid");
        top = canvas.transform.Find("top");
        system = canvas.transform.Find("system");
    }

    // ͨ���㼶ö�� �õ���Ӧ�㼶�ĸ�����
    public Transform GetLayerTransform(E_UI_Layer layer)
    {
        switch (layer)
        {
            case E_UI_Layer.Bot:
                return bot;

            case E_UI_Layer.Mid:
                return mid;

            case E_UI_Layer.Top:
                return top;

            case E_UI_Layer.System:
                return system;
        }

        return null;
    }

    /// <summary>
    ///     ͨ�����ֻ�ȡ��Ӧ��panel
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="name"></param>
    /// <returns></returns>
    public T GetPanel<T>(string name) where T : BasePanel
    {
        if (panelDic.ContainsKey(name)) return panelDic[name] as T;
        return null;
    }

    /// <summary>
    ///     ��ȡ����ע���Panel
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="name"></param>
    /// <returns></returns>
    public T GetRegisterPanel<T>(string name) where T : BasePanel
    {
        if (registerPanel.ContainsKey(name)) return registerPanel[name] as T;
        return null;
    }

    /// <summary>
    ///     ע��UI��壬��û��ͨ��showȥ���õ�PanelҲ���Ա�ȫ�ֻ�ã�����Ҫ���к�̨��������Ƶ�
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="panelName"></param>
    /// <param name="panel"></param>
    public void RegisterPanel<T>(string panelName, T panel) where T : BasePanel
    {
        registerPanel.TryAdd(panelName, panel);
    }

    /// <summary>
    ///     ��ʾ���
    ///     <para>Ĭ��ʹ��Address����</para>
    /// </summary>
    /// <typeparam name="T">���ű�����</typeparam>
    /// <param name="panelName">�����</param>
    /// <param name="layer">��ʾ����һ��</param>
    /// <param name="callBack">�����Ԥ���崴���ɹ��� ����������</param>
    public void ShowPanel<T>(string panelName, E_UI_Layer layer = E_UI_Layer.Mid, UnityAction<T> callBack = null)
        where T : BasePanel
    {
        if (panelDic.ContainsKey(panelName))
        {
            // �������Ѿ����ڣ�ֱ����ʾ�����ûص�����
            panelDic[panelName].ReOpen(); //���´򿪵Ķ������ReOpen
            panelDic[panelName].OpenPanel();
            panelDic[panelName].gameObject.SetActive(true); //��ʽ��UI����Ҫ��΢��һ��
            if (callBack != null)
                callBack(panelDic[panelName] as T);
            return;
        }

        // �첽����Prefab��Դ
        ResManager.Instance.LoadAsync<GameObject>(panelName, obj =>
            {
                var instantiatedObj = Instantiate(obj);
                //����ͼ��
                var father = GetLayerTransform(layer);

                // ���ø�����
                instantiatedObj.transform.SetParent(father, false); // �ڶ�������Ϊfalse��ʾ��������������

                // �������ı���λ�úʹ�С
                instantiatedObj.transform.localPosition = Vector3.zero;
                instantiatedObj.transform.localScale = Vector3.one;

                var rectTransform = instantiatedObj.GetComponent<RectTransform>();
                rectTransform.offsetMax = Vector2.zero;
                rectTransform.offsetMin = Vector2.zero;

                //�õ�Ԥ�������ϵ����ű�
                var panel = instantiatedObj.GetComponent<T>();
                // ������崴����ɺ���߼�
                if (callBack != null)
                    callBack(panel);
                panel.OpenPanel();

                panel.gameObject.SetActive(true);
                //����������
                panelDic.Add(panelName, panel);
            },
            LoadType.AddressAbles
        );
    }

    /// <summary>
    ///     �������
    /// </summary>
    /// <param name="panelName"></param>
    public void HidePanel(string panelName, bool isFade = true)
    {
        if (panelDic.ContainsKey(panelName))
        {
            if (isFade)
            {
                //panelDic[panelName].HideMe(() =>
                //{
                //GameObject.Destroy(panelDic[panelName].gameObject);
                //panelDic.Remove(panelName);  //ֱ��ɾ�����ݷ�������showPanel�еļ��panelDic�д�����ֱ����ʾ��Ϊһ��Ц��
                panelDic[panelName].gameObject.SetActive(false);
                //});
            }
            else
            {
                // ɾ������ɾ����Ӧ��������Ķ���/�ű���
                Destroy(panelDic[panelName].gameObject);
                // ɾ���ֵ�����洢�� ���ļ�ֵ��
                panelDic.Remove(panelName);
            }
        }
    }

    /// <summary>
    ///     ������壬ͨ��Panel����
    /// </summary>
    /// <param name="panel"></param>
    public void HidePanel(BasePanel panel)
    {
        foreach (var item in panelDic)
            if (item.Value == panel)
                item.Value.gameObject.SetActive(false);
    }

    private void DestroyPanel(string panelName)
    {
        // ��������GameObject�������ֵ����Ƴ���Ӧ����Ŀ
        if (panelDic.ContainsKey(panelName))
        {
            Destroy(panelDic[panelName].gameObject);
            panelDic.Remove(panelName);
        }
    }

    /// <summary>
    ///     ��ĳ��UI�������EventTrigger
    /// </summary>
    /// <param name="control"></param>
    /// <param name="type"></param>
    /// <param name="callBack"></param>
    public static void AddCustomEventListener(UIBehaviour control, EventTriggerType type,
        UnityAction<BaseEventData> callBack)
    {
        var trigger = control.GetComponent<EventTrigger>();
        if (trigger == null)
            trigger = control.gameObject.AddComponent<EventTrigger>();

        var entry = new EventTrigger.Entry();
        entry.eventID = type;
        entry.callback.AddListener(callBack);

        trigger.triggers.Add(entry);
    }

    public void EnterUI()
    {
        Time.timeScale = 0f;
    }

    public void ExitUI()
    {
        Time.timeScale = 1f;
    }

    /// <summary>
    ///     t
    ///     ��ȡ��ǰ��Ծ��Panel
    /// </summary>
    public BasePanel GetCurActivePanel()
    {
        foreach (var item in panelDic)
            if (item.Value.isActiveAndEnabled)
                return item.Value;

        return null;
    }
}